/// <reference path="typings/googlemaps/google.maps.d.ts" />

class GMap {
    element: Element;
    map: google.maps.Map;
    markers: Array<google.maps.Marker>;
    initOptions: google.maps.MapOptions;

    constructor(element: Element, options: google.maps.MapOptions) {
        this.element = element;
        this.markers = [];
        this.initOptions = options;
        options.mapTypeId = google.maps.MapTypeId.ROADMAP;
        this.map = new google.maps.Map(this.element, options);
    }

    addMarker(lat, lng, options): google.maps.Marker {
        var markerOptions = {
            position: new google.maps.LatLng(lat, lng),
            title: options.title != null ? options.title : void 0,
            map: this.map,
            animation: google.maps.Animation.DROP,
            icon: null,
            shadow: null
        };
        if (options.icon != null) {
            markerOptions.icon = new google.maps.MarkerImage(options.icon, null, null, new google.maps.Point(0, 32), new google.maps.Size(32, 32));
        }
        if (options.shadow != null) {
            markerOptions.shadow = new google.maps.MarkerImage(options.shadow, null, null, new google.maps.Point(0, 32), new google.maps.Size(59, 32));
        }
        var marker = new google.maps.Marker(markerOptions);
        if ((options.title != null) && (options.info != null)) {
            google.maps.event.addListener(marker, 'click', () => {
                var _infowindow = new google.maps.InfoWindow({
                    content: "<div class=\"marker-title\">" + options.title + "</div>" + "<div class=\"marker-info\">" + options.info + "</div>"
                });
                return _infowindow.open(this.map, marker);
            });
        }
        this.markers.push(marker);
        return marker;
    }

    deleteAllMarker():void {
        for (var _marker of this.markers) {
            _marker.setMap(null);
        }
    }

    fitCircle(latlng, km) {
        var bounds, circle;
        circle = new google.maps.Circle({
            center: latlng,
            radius: 1000 * (km - 3),
            map: this.map,
            fillOpacity: 0,
            strokeOpacity: 0
        });
        bounds = circle.getBounds();
        return this.map.fitBounds(bounds);
    }

    loadKml(url) {
        var Layer = new google.maps.KmlLayer(url, {
            suppressInfoWindows: false
        });
        return Layer.setMap(this.map);
    };

    geocode(address, callback) {
        var geocoder = new google.maps.Geocoder();
        return geocoder.geocode({
            'address': address
        }, function (results, status) {
            var latlng, location;
            if (status === google.maps.GeocoderStatus.OK) {
                location = results[0].geometry.location;
                latlng = new google.maps.LatLng(location.lat(), location.lng());
                return callback(latlng);
            } else {
                return alert("Geocode was not successful for the following reason: " + status);
            }
        });
    }

    setCurrentPosition(errorCallback: Function = () => { }) {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                var pos = {
                    lat: position.coords.latitude,
                    lng: position.coords.longitude
                };
                
                this.setCenter(pos);
            }, function () {
                errorCallback();
            });
        } else {
            // Browser doesn't support Geolocation
            errorCallback();
        }
    }

    setCenter(lat: number, lng: number, zoom: number = 0) {
        this.map.setCenter(new google.maps.LatLng(lat, lng));
        if(zoom)
            this.map.setZoom(zoom);
    }
}